package com.skyable.common.utils;

import java.text.DecimalFormat;
import java.text.Format;
import java.util.Random;

/**
 * @author GaoYuan
 * @date 2019/11/4 15:12
 * @desc 字符串工具函数
 */
public final class StringUtil {
	private static final String REG_VALIDATOR_IP = "^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}$";
	private static Random       random         = new Random();
	/**
	 * 检查字符串是否为空
	 * <p>
	 * 为null或者长度为0视为空字符串
	 *
	 * @param value
	 *            要检查的字符串
	 * @param trim
	 *            是否去掉头尾的特定字符
	 * @param trimChars
	 *            要去掉的特定字符
	 * @return
	 */
	public static boolean isEmpty(String value, boolean trim, char... trimChars) {
		if (trim) {
			return value == null || trim(value, trimChars).length() <= 0;
		}
		return value == null || value.length() <= 0;
	}

	/**
	 * 检查字符串是否为空
	 * <p>
	 * 为null或者长度为0视为空字符串
	 *
	 * @param value
	 *            要检查的字符串
	 * @param trim
	 *            是否去掉头尾的空格
	 * @return
	 */
	public static boolean isEmpty(String value, boolean trim) {
		return isEmpty(value, trim, ' ');
	}

	/**
	 * 检查字符串是否为空
	 * <p>
	 * 为null或者长度为0视为空字符串
	 *
	 * @param value
	 *            要检查的字符串
	 * @return
	 */
	public static boolean isEmpty(String value) {
		return isEmpty(value, false);
	}

	/**
	 * 将对象转化为字符串类型
	 *
	 * @param value
	 *            要转化的对象
	 * @return
	 */
	public static String toSafeString(Object value) {
		return value == null ? "" : value.toString();
	}

	/**
	 * 如果为null，转换为""
	 *
	 * @param value
	 * @return
	 */
	public static String nullSafeString(String value) {
		return value == null ? "" : value;
	}

	/**
	 * 确保存入数据库的string值不会引起数据库报错。
	 * <p>
	 * 1. 数据库不允许为null，value为nul时返回""；<br />
	 * 2. 超过最大长度时截断字符串。
	 *
	 * @param value
	 *            要存入数据库的字符串值。
	 * @param nullable
	 *            是否允许为null。
	 * @param maxLength
	 *            最大长度。
	 * @return
	 */
	public static String dbSafeString(String value, boolean nullable,
			int maxLength) {
		if (value == null) {
			if (nullable) {
				return null;
			}
			return nullSafeString(value);
		}
		if (value.length() > maxLength) {
			return value.substring(0, maxLength);
		}
		return value;
	}

	/**
	 * 去掉头尾空格字符
	 *
	 * @param value
	 *            待处理的字符串
	 * @return
	 */
	public static String trim(String value) {
		return trim(3, value, ' ');
	}

	/**
	 * 去除字符串头尾的特定字符
	 *
	 * @param value
	 *            待处理的字符串
	 * @param chars
	 *            需要去掉的特定字符
	 * @return
	 */
	public static String trim(String value, char... chars) {
		return trim(3, value, chars);
	}

	/**
	 * 去除字符串头部的特定字符
	 *
	 * @param value
	 *            待处理的字符串
	 * @param chars
	 *            需要去掉的特定字符
	 * @return
	 */
	public static String trimStart(String value, char... chars) {
		return trim(1, value, chars);
	}

	/**
	 * 去除字符串尾部的特定字符
	 *
	 * @param value
	 *            待处理的字符串
	 * @param chars
	 *            需要去掉的特定字符
	 * @return
	 */
	public static String trimEnd(String value, char... chars) {
		return trim(2, value, chars);
	}

	/**
	 * 去掉字符串头尾特定字符
	 *
	 * @param mode
	 *            <li>1: 去掉头部特定字符； <li>2: 去掉尾部特定字符； <li>3: 去掉头尾特定字符；
	 * @param value
	 *            待处理的字符串
	 * @param chars
	 *            需要去掉的特定字符
	 * @return
	 */
	private static String trim(int mode, String value, char... chars) {
		if (value == null || value.length() <= 0) {
			return value;
		}

		int startIndex = 0, endIndex = value.length(), index = 0;
		if (mode == 1 || mode == 3) {
			// trim头部
			while (index < endIndex) {
				if (contains(chars, value.charAt(index++))) {
					startIndex++;
					continue;
				}
				break;
			}
		}

		if (startIndex >= endIndex) {
			return "";
		}

		if (mode == 2 || mode == 3) {
			// trim尾部
			index = endIndex - 1;
			while (index >= 0) {
				if (contains(chars, value.charAt(index--))) {
					endIndex--;
					continue;
				}
				break;
			}
		}

		if (startIndex >= endIndex) {
			return "";
		}
		if (startIndex == 0 && endIndex == value.length() - 1) {
			return value;
		}

		return value.substring(startIndex, endIndex);
	}

	private static boolean contains(char[] chars, char chr) {
		if (chars == null || chars.length <= 0) {
			return false;
		}
		for (int i = 0; i < chars.length; i++) {
			if (chars[i] == chr) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 判断是否是有效的IP地址。
	 *
	 * @param value
	 * @return
	 */
	public static boolean isIp(String value) {
		if (isEmpty(value)) {
			return false;
		}
		return value.matches(REG_VALIDATOR_IP);
	}

	/**
	 * 判断是否是数字
	 *
	 * @param value
	 * @return
	 */
	public static boolean isNumber(String value) {
		if (isEmpty(value, true)) {
			return false;
		}
		return value.matches("^[0-9]*$");
	}

	/**
     * 生成一个指定长度的字符串
     */
    public static String genRandomString(int length) {
        String base = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYAC0123456789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(base.charAt(random.nextInt(base.length())));
        }
        return sb.toString();
    }

    /**
     * 生成复杂码函数
     * @param lenght
     * @return
     */
	public static String generatePass(int lenght) {

		String[] pswdStr = { "qwertyuiopasdfghjklzxcvbnm",
				"QWERTYUIOPASDFGHJKLZXCVBNM", "0123456789",
				"~!@#$%^&*()_+{}|<>?:{}" };

		int pswdLen = lenght;
		String pswd = " ";
		char[] chs = new char[pswdLen];
		for (int i = 0; i < pswdStr.length; i++) {

			int idx = (int) (Math.random() * pswdStr[i].length());
			chs[i] = pswdStr[i].charAt(idx);

		}

		for (int i = pswdStr.length; i < pswdLen; i++) {

			int arrIdx = (int) (Math.random() * pswdStr.length);
			int strIdx = (int) (Math.random() * pswdStr[arrIdx].length());

			chs[i] = pswdStr[arrIdx].charAt(strIdx);
		}

		for (int i = 0; i < 1000; i++) {
			int idx1 = (int) (Math.random() * chs.length);
			int idx2 = (int) (Math.random() * chs.length);

			if (idx1 == idx2) {
				continue;
			}

			char tempChar = chs[idx1];
			chs[idx1] = chs[idx2];
			chs[idx2] = tempChar;
		}

		pswd = new String(chs);
		return pswd;
	}

	public static String formatNum(String pattern, Integer num) {
		//实例化format，格式为“000”
		Format format = new DecimalFormat(pattern);
		String count = format.format(num);
		return count;
	}

	public static String generateVerityCode(Integer num) {
		StringBuilder verityCode = new StringBuilder();
		Random random = new java.util.Random();
		for(int i = 0; i<num; i++) {
			int anInt = random.nextInt(10);
			verityCode.append(anInt);
		}
		return verityCode.toString();
	}
}
